package com.sunwayworld.basemodule.common.clickhouse.client;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import ru.yandex.clickhouse.BalancedClickhouseDataSource;
import ru.yandex.clickhouse.ClickHouseDataSource;
import ru.yandex.clickhouse.settings.ClickHouseProperties;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author jiaorg
 * @date 2022-09-07 14:20
 * @description:获取客户端连接
 * @version: 1.0.0
 */
@Component
public class ClickHouseConnection {
    private final static Logger logger = LoggerFactory.getLogger(ClickHouseConnection.class);
    /**
     * 数据库连接
     */
    private static ThreadLocal<Connection> conn = new ThreadLocal<>();
    /**
     * 可重入锁
     */
    private static Lock lock = new ReentrantLock();

    private static DataSource dataSource;

    /*@Autowired
    private ClickHouseConfig clickHouseConfig;*/

    /**
     * 获取connection，关闭自动提交，其实clickhouse不支持回滚的
     * （处理成功commit，异常捕获rollback），假如后面新的版本支持了
     *
     * @return
     */
    public Connection getConnection() {
        if (getDataSource() == null) {
            logger.error("获取连接池失败，dataSource：[{}]", getDataSource());
            throw new RuntimeException(" clickHouseDataSource is null ");
        }
        Connection connection = null;
        lock.lock();
        try {
            connection = conn.get();
            if (connection == null || connection.isClosed()) {
                connection = getDataSource().getConnection();
                conn.set(connection);
            }
        } catch (Exception e) {
            logger.error("getConnection:{}",e);
        } finally {
            lock.unlock();
        }
        return connection;
    }

    /**
     * 释放连接
     */
    public void closeConnection() {
        if (getDataSource() == null) {
            logger.error("获取连接池失败，dataSource：[{}]", getDataSource());
            throw new RuntimeException(" clickHouseDataSource is null ");
        }
        lock.lock();
        try {
            Connection connection = conn.get();
            if (connection!=null) {
                connection.close();
                conn.remove();
            }
        } catch (Exception e) {
            logger.error("closeConnection:{}",e);
        } finally {
            lock.unlock();
        }
    }

    /**
     * 获取数据源
     *
     * @return
     */
    public DataSource getDataSource() {
        try {
            /** 设置clickHouse连接属性 */
            ClickHouseProperties clickHouseProperties = new ClickHouseProperties();
            /*clickHouseProperties.setUser(clickHouseConfig.getUsername());
            clickHouseProperties.setPassword(clickHouseConfig.getPassword());
            clickHouseProperties.setSocketTimeout(clickHouseConfig.getSocketTimeout());
            String address = clickHouseConfig.getUrl();*/
            String address = "";
            logger.debug("clickHouse初始化数据源地址[{}]", address);
            // if (address.indexOf(ClickHouseCommonProperties.DELIMITER) > 0) {
            if (address.indexOf("") > 0) {
                //集群
                dataSource = new BalancedClickhouseDataSource(address, clickHouseProperties);
            } else {
                //单机
                dataSource = new ClickHouseDataSource(address, clickHouseProperties);
            }
            if (dataSource != null) {
                logger.debug("clickHouse数据源初始化成功");
            }
            if (dataSource == null) {
                logger.error("获取数据源失败，dataSource：[{}]", dataSource);
                throw new RuntimeException(" clickHouseDataSource is null ");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataSource;
    }

}
